#include "QBSortVContainer.h"
#include <sstream>  
#include "BondInfo.h"
#include "BondCDCPriceInfo.h"
#include "BondContainer.h"
#include "SSCFETSQuote.h"
#include "qbprotocol/include/SSQBAModel.h"
#include "BondCSIPriceInfo.h"

#define SP_ASSERT //
namespace{
	inline bool IsEmpty(const char* str){
		// 旧代码是 strlen(str)<=0;
		return str == nullptr || *str == '\0';
	}
	inline bool CheckPriceZero(double price)
	{
		// 之前代码中,不检查价格<=PRECISION5,会导致JIRA 10761 的问题
		return price <= PRECISION5&&price >= -PRECISION5;
	}
}
const char* GetBidEstPrice(const REPORT &report, const CBondInfo *pBond,const int nBondIndex, bool bIsCDCAuthValid)
{
	SP_ASSERT( pBond != nullptr );
	if ( strcmp(report.m_bidinfo.m_price_status,"0")==0) 
	{
		return "--";
	}

	double dBidPrice = atof(report.m_bidinfo.m_yield_price);
	int qt = atoi(report.m_bidinfo.m_quotetype);
	if (qt != 3 && (pBond->IsBondABS() || pBond->IsTransBond()))//quotetype不是收益率，仅ABS和可转债判定0-30
	{
		if (dBidPrice <= 0.0 || dBidPrice >= 30.0)
		{
			return "--";
		}
	}

	double dValue = CBondCDCPriceInfo::instance().GetYesterdayCDCPriceGap(bIsCDCAuthValid, nBondIndex, CBondCDCPriceInfo::price_type_yield, true, report.m_bidinfo.m_yield_price, INVALID_CDC_VALUE, false);
	if (dValue <= INVALID_CDC_VALUE) return "--";

	static char sValue[30] = {0};
	memset(sValue,0,sizeof(sValue));
	FMTBUF(sValue,"%.2f",dValue);
	return sValue;
}

std::string GetBidEstPrice(const char* pBidPrice, const CBondInfo *pBond, const int nBondIndex, bool bIsCDCAuthValid)
{
	SP_ASSERT( pBond != nullptr );

	double dBidPrice = atof(pBidPrice);
	if ( dBidPrice>=30)
	{
		return "--";
	}

	double dValue = CBondCDCPriceInfo::instance().GetYesterdayCDCPriceGap(bIsCDCAuthValid, nBondIndex, CBondCDCPriceInfo::price_type_yield, true, pBidPrice, INVALID_CDC_VALUE, false);
	if (dValue <= INVALID_CDC_VALUE) return "--";

	char sValue[30] = {0};
	FMTBUF(sValue,"%.2f",dValue);
	return std::string(sValue);
}


const char* GetBidEstPrice(int nBondIndex, const std::string &sBrokerID, bool bIsCDCAuthValid)
{
	REPORT report;
	memset(&report,0,sizeof(REPORT));
	if ( CBondContainer::instance().GetCompanyRepById(nBondIndex,sBrokerID.c_str(),report) )
	{
		return GetBidEstPrice(report, &CBondContainer::instance().ElementAtR(nBondIndex), nBondIndex, bIsCDCAuthValid);
	}

	return "--";
}

const char* GetBidEstPriceBySettlement(int nBondIndex, const std::string& sBrokerID, bool bIsCDCAuthValid, BYTE btSettlement)
{
	REPORT report;
	memset(&report, 0, sizeof(REPORT));
	if (CBondContainer::instance().GetCompanyRepByIdAndSettlement(nBondIndex, sBrokerID.c_str(), btSettlement, report))
	{
		return GetBidEstPrice(report, &CBondContainer::instance().ElementAtR(nBondIndex), nBondIndex, bIsCDCAuthValid);
	}

	return "--";
}


const char* GetBidEstPrice(const CFETSQUOTE *report, const CBondInfo *pBond, const int nBondIndex, bool bIsCDCAuthValid)
{
	SP_ASSERT(pBond != nullptr);
	SP_ASSERT(report != nullptr);

	if (strcmp(report->m_BidPriceYield, "0") == 0
		|| strcmp(report->m_BidPriceYield, "bid") == 0
		|| strcmp(report->m_BidPriceYield, "Bid") == 0 || IsEmpty(report->m_BidPriceYield))
		return "--";

	double dBidPrice = atof(report->m_BidPriceYield);

	double dValue = CBondCDCPriceInfo::instance().GetYesterdayCDCPriceGap(bIsCDCAuthValid, nBondIndex, CBondCDCPriceInfo::price_type_yield, true, report->m_BidPriceYield, INVALID_CDC_VALUE, false);
	if (dValue <= INVALID_CDC_VALUE)		return "--";

	static char sValue[30] = { 0 };
	memset(sValue, 0, sizeof(sValue));
	FMTBUF(sValue, "%.2f", dValue);
	return sValue;
}

const char* GetEstPriceOfr(const REPORT &report, const CBondInfo *pBond, const int nBondIndex, bool bIsCDCAuthValid)
{
	SP_ASSERT( pBond != nullptr );

	if (strcmp(report.m_askinfo.m_price_status,"0")==0 ) 
	{
		return "--";
	}

	double dOfrPrice = atof(report.m_askinfo.m_yield_price);
	int qt = atoi(report.m_askinfo.m_quotetype);
	if (qt != 3 && (pBond->IsBondABS() || pBond->IsTransBond()))//quotetype不是收益率，仅ABS和可转债判定0-30
	{
		if (dOfrPrice <= 0.0 || dOfrPrice >= 30.0)
		{
			return "--";
		}
	}
	
	double dValue = CBondCDCPriceInfo::instance().GetYesterdayCDCPriceGap(bIsCDCAuthValid, nBondIndex, CBondCDCPriceInfo::price_type_yield, false, report.m_askinfo.m_yield_price, INVALID_CDC_VALUE, false);
	if (dValue <= INVALID_CDC_VALUE)		return "--";
	static char sValue[30] = {0};
	memset(sValue,0,sizeof(sValue));
	FMTBUF(sValue, "%.2f", dValue);
	return sValue;
}

std::string GetEstPriceOfr(const char* pOfrPrice, const CBondInfo *pBond, const int nBondIndex, bool bIsCDCAuthValid)
{
	SP_ASSERT( pBond != nullptr );
	SP_ASSERT( pOfrPrice != nullptr );


	double dOfrPrice = atof(pOfrPrice);
	if ( dOfrPrice>=30)
	{
		return "--";
	}

	double dValue = CBondCDCPriceInfo::instance().GetYesterdayCDCPriceGap(bIsCDCAuthValid, nBondIndex, CBondCDCPriceInfo::price_type_yield, false, pOfrPrice, INVALID_CDC_VALUE, false);
	if (dValue <= INVALID_CDC_VALUE) return "--";

	char sValue[30] = {0};
	FMTBUF(sValue,"%.2f",dValue);
	return std::string(sValue);
}


const char* GetEstPriceOfr(int nBondIndex, const std::string &sBrokerID, bool bIsCDCAuthValid)
{
	REPORT report;
	memset(&report,0,sizeof(REPORT));
	if ( CBondContainer::instance().GetCompanyRepById(nBondIndex,sBrokerID.c_str(),report) )
	{
		return GetEstPriceOfr(report, &CBondContainer::instance().ElementAtR(nBondIndex), nBondIndex, bIsCDCAuthValid);
	}

	return "--";
}

const char* GetEstPriceOfrBySettlement(int nBondIndex, const std::string& sBrokerID, bool bIsCDCAuthValid, BYTE btSettlement)
{
	REPORT report;
	memset(&report, 0, sizeof(REPORT));
	if (CBondContainer::instance().GetCompanyRepByIdAndSettlement(nBondIndex, sBrokerID.c_str(), btSettlement, report))
	{
		return GetEstPriceOfr(report, &CBondContainer::instance().ElementAtR(nBondIndex), nBondIndex, bIsCDCAuthValid);
	}

	return "--";
}

const char* GetEstPriceOfr(const CFETSQUOTE *report, const CBondInfo *pBond, const int nBondIndex, bool bIsCDCAuthValid)
{
	SP_ASSERT(pBond != nullptr);
	SP_ASSERT(report != nullptr);

	if (strcmp(report->m_OfrPriceYield, "0") == 0
		|| strcmp(report->m_OfrPriceYield, "bid") == 0
		|| strcmp(report->m_OfrPriceYield, "Bid") == 0 || IsEmpty(report->m_OfrPriceYield))
		return "--";
	double dOfrPrice = atof(report->m_OfrPriceYield);

	double dValue = CBondCDCPriceInfo::instance().GetYesterdayCDCPriceGap(bIsCDCAuthValid, nBondIndex, CBondCDCPriceInfo::price_type_yield, false, report->m_OfrPriceYield, INVALID_CDC_VALUE, false);
	if (dValue <= INVALID_CDC_VALUE) return "--";
	static char sValue[30] = { 0 };
	memset(sValue, 0, sizeof(sValue));
	FMTBUF(sValue, "%.2f", dValue);
	return sValue;
}

const char* GetBidCsiPrice( const REPORT &report,const CBondInfo *pBond )
{
	SP_ASSERT( pBond != nullptr );

	if (/*IsEmpty(pBond->GetCSYield()) || */strcmp(report.m_bidinfo.m_price_status, "0") == 0
		|| IsEmpty(report.m_bidinfo.m_yield_price))
	{
		return "--";
	}

	double dBidPrice = atof(report.m_bidinfo.m_yield_price);
	int qt = atoi(report.m_bidinfo.m_quotetype);
	if (qt != 3 && (pBond->IsBondABS() || pBond->IsTransBond()))//quotetype不是收益率，仅ABS和可转债判定0-30
	{
		if (dBidPrice <= 0.0 || dBidPrice >= 30.0)
		{
			return "--";
		}
	}

	//double dValue = (dBidPrice - atof(pBond->GetCSYield())) * 100;
	//static char sValue[30] = "--";//{0};
	//memset(sValue,0,sizeof(sValue));
	//FMTBUF(sValue, "%.2f", dValue);
	//return sValue;
	
	xCSIUint_c xUnit;
	if (!CBondCSInfo::instance().GetCsiUnit(pBond->GetCombBondKey(), xUnit))
		return "--";

	if (!xUnit.IsHaveExercise() && !xUnit.IsHaveMarturity())
		return "--";

	double dExercise = xUnit.IsHaveExercise() ? xUnit.m_dYieldToExercise : _INVALID_CSI_VALUE;
	double dMaturity = xUnit.IsHaveMarturity() ? xUnit.m_dYieldToMaturity : _INVALID_CSI_VALUE;

	//double dBidPrice = atof(report.m_bidinfo.m_yield_price);

	static char sValue[30] = "--";

	double dRet = _INVALID_CSI_VALUE;
	if (dExercise > _INVALID_CSI_VALUE && dMaturity > _INVALID_CSI_VALUE)
	{
		dExercise = dBidPrice - dExercise;
		dMaturity = dBidPrice - dMaturity;
		dRet = abs(dExercise) < abs(dMaturity) ? dExercise : dMaturity;
	}
	else if (dExercise > _INVALID_CSI_VALUE)
	{
		dRet = dBidPrice - dExercise;
	}
	else if (dMaturity > _INVALID_CSI_VALUE)
	{
		dRet = dBidPrice - dMaturity;
	}

	memset(sValue, 0, sizeof(sValue));
	FMTBUF(sValue, "%.4f", dRet * 100);

	return sValue;
}

const char* GetBidCsiPrice( int nBondIndex,const std::string &sBrokerID )
{
	REPORT report;
	memset(&report,0,sizeof(REPORT));
	if ( CBondContainer::instance().GetCompanyRepById(nBondIndex,sBrokerID.c_str(),report) )
	{
		return GetBidCsiPrice(report, &CBondContainer::instance().ElementAtR(nBondIndex));
	}

	return "--";
}

const char* GetBidCsiPriceBySettlement(int nBondIndex, const std::string& sBrokerID, BYTE btSettlement)
{
	REPORT report;
	memset(&report, 0, sizeof(REPORT));
	if (CBondContainer::instance().GetCompanyRepByIdAndSettlement(nBondIndex, sBrokerID.c_str(), btSettlement, report))
	{
		return GetBidCsiPrice(report, &CBondContainer::instance().ElementAtR(nBondIndex));
	}
	return "--";
}

const char* GetBidCsiPrice(const CFETSQUOTE *report, const CBondInfo *pBond)
{
	SP_ASSERT(pBond != nullptr);
	SP_ASSERT(report != nullptr);
	if (/*IsEmpty(pBond->GetCSYield()) || */strcmp(report->m_BidPriceYield, "0") == 0
		|| strcmp(report->m_BidPriceYield, "bid") == 0
		|| strcmp(report->m_BidPriceYield, "Bid") == 0 || IsEmpty(report->m_BidPriceYield))
	{
		return "--";
	}

	double dBidPrice = atof(report->m_BidPriceYield);
	if (dBidPrice <= 0.0 || dBidPrice >= 30.0)
		return "--";

	xCSIUint_c xUnit;
	if (!CBondCSInfo::instance().GetCsiUnit(pBond->GetCombBondKey(), xUnit))
		return "--";

	if (!xUnit.IsHaveExercise() && !xUnit.IsHaveMarturity())
		return "--";

	double dExercise = xUnit.IsHaveExercise() ? xUnit.m_dYieldToExercise : _INVALID_CSI_VALUE;
	double dMaturity = xUnit.IsHaveMarturity() ? xUnit.m_dYieldToMaturity : _INVALID_CSI_VALUE;

	static char sValue[30] = "--";

	double dRet = _INVALID_CSI_VALUE;
	if (dExercise > _INVALID_CSI_VALUE && dMaturity > _INVALID_CSI_VALUE)
	{
		dExercise = dBidPrice - dExercise;
		dMaturity = dBidPrice - dMaturity;
		dRet = abs(dExercise) < abs(dMaturity) ? dExercise : dMaturity;
	}
	else if (dExercise > _INVALID_CSI_VALUE)
	{
		dRet = dBidPrice - dExercise;
	}
	else if (dMaturity > _INVALID_CSI_VALUE)
	{
		dRet = dBidPrice - dMaturity;
	}

	memset(sValue, 0, sizeof(sValue));
	FMTBUF(sValue, "%.4f", dRet*100.0000);

	return sValue;
}

const char* GetCsiPriceOfr( const REPORT &report,const CBondInfo *pBond )
{
	SP_ASSERT( pBond != nullptr );

	if (/*IsEmpty(pBond->GetCSYield()) || */strcmp(report.m_askinfo.m_price_status,"0")==0
		|| IsEmpty(report.m_askinfo.m_yield_price))
	{
		return "--";
	}

	double dOfrPrice = atof(report.m_askinfo.m_yield_price);
	int qt = atoi(report.m_askinfo.m_quotetype);
	if (qt != 3 && (pBond->IsBondABS() || pBond->IsTransBond()))//quotetype不是收益率，仅ABS和可转债判定0-30
	{
		if (dOfrPrice <= 0.0 || dOfrPrice >= 30.0)
		{
			return "--";
		}
	}
	
	//double dValue = (atof(pBond->GetCSYield()) - dOfrPrice) * 100;
	static char sValue[30] = {0};
	//memset(sValue,0,sizeof(sValue));
	//FMTBUF(sValue, "%.2f", dValue);
	//return sValue;

	xCSIUint_c xUnit;
	if (!CBondCSInfo::instance().GetCsiUnit(pBond->GetCombBondKey(), xUnit))
		return "--";

	if (!xUnit.IsHaveExercise() && !xUnit.IsHaveMarturity())
		return "--";

	double dExercise = xUnit.IsHaveExercise() ? xUnit.m_dYieldToExercise : _INVALID_CSI_VALUE;
	double dMaturity = xUnit.IsHaveMarturity() ? xUnit.m_dYieldToMaturity : _INVALID_CSI_VALUE;

	//double dOfrPrice = atof(report.m_askinfo.m_yield_price);

	int nQuoteType = atoi(report.m_askinfo.m_quotetype);
	if (nQuoteType != 3 && (pBond->IsBondABS() || pBond->IsTransBond()))//quotetype不是收益率，仅ABS和可转债判定0-30
	{
		if (dOfrPrice <= 0.0 || dOfrPrice >= 30.0)
			return "--";
	}

	double dRet = _INVALID_CSI_VALUE;
	if (dExercise > _INVALID_CSI_VALUE && dMaturity > _INVALID_CSI_VALUE)
	{
		dExercise = dExercise - dOfrPrice;
		dMaturity = dMaturity - dOfrPrice;
		dRet = abs(dExercise) < abs(dMaturity) ? dExercise : dMaturity;
	}
	else if (dExercise > _INVALID_CSI_VALUE)
	{
		dRet = dExercise - dOfrPrice;
	}
	else if (dMaturity > _INVALID_CSI_VALUE)
	{
		dRet = dMaturity - dOfrPrice;
	}

	memset(sValue, 0, sizeof(sValue));
	FMTBUF(sValue, "%.4f", dRet * 100.0000);

	return sValue;
}

const char* GetCsiPriceOfr( int nBondIndex, const std::string& sBrokerID )
{
	REPORT report;
	memset(&report,0,sizeof(REPORT));
	if ( CBondContainer::instance().GetCompanyRepById(nBondIndex,sBrokerID.c_str(),report) )
	{
		return GetCsiPriceOfr(report, &CBondContainer::instance().ElementAtR(nBondIndex));
	}

	return "--";
}

const char* GetCsiPriceOfrBySettlement(int nBondIndex, const std::string& sBrokerID, BYTE btSettlement)
{
	REPORT report;
	memset(&report, 0, sizeof(REPORT));
	if (CBondContainer::instance().GetCompanyRepByIdAndSettlement(nBondIndex, sBrokerID.c_str(), btSettlement, report))
	{
		return GetCsiPriceOfr(report, &CBondContainer::instance().ElementAtR(nBondIndex));
	}

	return "--";
}

const char* GetCsiPriceOfr(const CFETSQUOTE *report, const CBondInfo *pBond)
{
	SP_ASSERT(pBond != nullptr);
	SP_ASSERT(report != nullptr);

	if (strcmp(report->m_OfrPriceYield, "0") == 0
		|| strcmp(report->m_OfrPriceYield, "ofr") == 0
		|| strcmp(report->m_OfrPriceYield, "Ofr") == 0 || IsEmpty(report->m_OfrPriceYield))
	{
		return "--";
	}

	double dOfrPrice = atof(report->m_OfrPriceYield);
	if (pBond->IsBondABS() || pBond->IsTransBond())//quotetype不是收益率，仅ABS和可转债判定0-30
	{
		if (dOfrPrice <= 0.0 || dOfrPrice >= 30.0)
			return "--";
	}

	static char sValue[30] = { 0 };
	xCSIUint_c xUnit;
	if (!CBondCSInfo::instance().GetCsiUnit(pBond->GetCombBondKey(), xUnit))
		return "--";

	if (!xUnit.IsHaveExercise() && !xUnit.IsHaveMarturity())
		return "--";

	double dExercise = xUnit.IsHaveExercise() ? xUnit.m_dYieldToExercise : _INVALID_CSI_VALUE;
	double dMaturity = xUnit.IsHaveMarturity() ? xUnit.m_dYieldToMaturity : _INVALID_CSI_VALUE;

	double dRet = _INVALID_CSI_VALUE;
	if (dExercise > _INVALID_CSI_VALUE && dMaturity > _INVALID_CSI_VALUE)
	{
		dExercise = dExercise - dOfrPrice;
		dMaturity = dMaturity - dOfrPrice;
		dRet = abs(dExercise) < abs(dMaturity) ? dExercise : dMaturity;
	}
	else if (dExercise > _INVALID_CSI_VALUE)
	{
		dRet = dExercise - dOfrPrice;
	}
	else if (dMaturity > _INVALID_CSI_VALUE)
	{
		dRet = dMaturity - dOfrPrice;
	}

	memset(sValue, 0, sizeof(sValue));
	FMTBUF(sValue, "%.4f", dRet*100.0000);
	return sValue;
}

const char*  GetCsi_CdcPrice(const CBondInfo *pBond, const int nBondIndex, bool bIsCDCAuthValid)
{
	SP_ASSERT(pBond != nullptr);

	static char sValue[30] = { 0 };
	memset(sValue, 0, sizeof(sValue));

	double dCdcExercise = INVALID_CDC_VALUE;
	double dCdcMaturity = INVALID_CDC_VALUE;
	CBondCDCPriceInfo::instance().GetExerciseAndMaturity(bIsCDCAuthValid, nBondIndex, dCdcExercise, dCdcMaturity);

	double dCsiExercise = _INVALID_CSI_VALUE;
	double dCsiMaturity = _INVALID_CSI_VALUE;
	xCSIUint_c xcsi;
	if (CBondCSInfo::instance().GetCsiUnit(pBond->GetCombBondKey(), xcsi))
	{
		dCsiExercise = xcsi.m_dYieldToExercise;
		dCsiMaturity = xcsi.m_dYieldToMaturity;
	}
	else
	{
		return "--";
	}

	bool bExerciseValid = false;
	char szExercise[32] = { 0 };
	if (dCdcExercise <= INVALID_CDC_VALUE || dCsiExercise <= _INVALID_CSI_VALUE)
	{
		FMTBUF(szExercise, "%s", "--");
	}
	else
	{
		bExerciseValid = true;
		FMTBUF(szExercise, "%.4f", dCsiExercise - dCdcExercise);
	}

	bool bMaturityValid = false;
	std::string sExercise;
	char szMaturity[32] = { 0 };
	if (dCdcMaturity <= INVALID_CDC_VALUE || dCsiMaturity <= _INVALID_CSI_VALUE)
	{
		FMTBUF(szMaturity, "%s", "--");
	}
	else
	{
		bMaturityValid = true;
		FMTBUF(szMaturity, "%.4f", dCsiMaturity - dCdcMaturity);
	}

	if (bExerciseValid && bMaturityValid)
	{
		FMTBUF(sValue, "%.4f", dCsiExercise - dCdcExercise);
	}
	else if (bExerciseValid)
	{
		FMTBUF(sValue, "%s", szExercise);
	}
	else if (bMaturityValid)
	{
		FMTBUF(sValue, "%s", szMaturity);
	}
	else
	{
		FMTBUF(sValue, "%s", "--");
	}	

	return sValue;
}

const char* GetCsi_CdcPrice(int nBondIndex, bool bIsCDCAuthValid)
{
	if (CBondContainer::instance().IsValidIndex(nBondIndex))
	{
		return GetCsi_CdcPrice(&CBondContainer::instance().ElementAtR(nBondIndex), nBondIndex, bIsCDCAuthValid);
	}

	return "--";
}

const char* GetCleanPriceDiv( const char* lpszTknCleanPrice,const char* lpszCdcCleanPrice )
{
	if ( lpszCdcCleanPrice == nullptr || lpszCdcCleanPrice==nullptr )
	{
		return "--";
	}

	if ( IsEmpty(lpszTknCleanPrice) || IsEmpty(lpszCdcCleanPrice) )
	{
		return "--";
	}

	float fCleanPrice = atof(lpszTknCleanPrice);
	float fCdcCleanPrice = atof(lpszCdcCleanPrice);
	if ( fabs(fCdcCleanPrice) <= 0.000001 )
	{
		return "--";
	}

	float fValue = (fCleanPrice / fCdcCleanPrice - 1) * 100;

	static char sValue[30] = {0};
	memset(sValue,0,sizeof(sValue));
	FMTBUF(sValue,"%.4f", fValue);

	return sValue;
}

const char* GetYieldDiv( const char* lpszCdcVal,const char* lpszTknYield )
{
	if ( lpszCdcVal == nullptr || lpszTknYield==nullptr )
	{
		return "--";
	}

	if ( IsEmpty(lpszCdcVal) || IsEmpty(lpszTknYield) )
	{
		return "--";
	}

	float fValue = atof(lpszCdcVal) - atof(lpszTknYield);

	static char sValue[30] = {0};
	memset(sValue,0,sizeof(sValue));
	FMTBUF(sValue, "%.4f", fValue);
	return sValue;
}

bool GetMarketStreamInfo(const  CBondInfo *pBond, const char* lpszBrokerID, std::vector<MarketStreamInfo>* pStream, MarketStreamInfo &streamInfo)
{
	if (pBond ==nullptr || lpszBrokerID == nullptr || pStream == nullptr )
	{
		return false;
	}

	std::vector<MarketStreamInfo>::iterator itor = pStream->begin();
	for(;itor!=pStream->end();++itor)
	{
		if(strcmp(pBond->GetBondKey(),itor->m_body.m_bondkey)==0&&strcmp(pBond->GetListedMarket(),itor->m_body.m_listedmarket)==0&&strcmp(lpszBrokerID,itor->m_company_id)==0)
		{
			streamInfo = *itor;
			return true;
		}
	}

	return false;
}

bool IsEqual( double dVal1,double dVal2 )
{
	if ( fabs(dVal1-dVal2) <= PRECISION6 )
	{
		return true;
	}

	return false;
}

bool IsLess( double dVal1,double dVal2 )
{
	if ( fabs(dVal1-dVal2) <= PRECISION6  )
	{
		return false;
	}

	return dVal1 < dVal2;
}

bool IsLessAndEqual( double dVal1,double dVal2 )
{
	if ( fabs(dVal1-dVal2) <= PRECISION6  )
	{
		return true;
	}	

	return dVal1 < dVal2;
}

bool IsGreater( double dVal1,double dVal2 )
{
	if ( fabs(dVal1-dVal2) <= PRECISION6  )
	{
		return false;
	}

	return dVal1 > dVal2;
}

bool IsGreaterAndEqual( double dVal1,double dVal2 )
{
	if ( fabs(dVal1-dVal2) <= PRECISION6  )
	{
		return true;
	}

	return dVal1 > dVal2;
}